﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Windows;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using Microsoft.Win32;
using Morphine.Base;
using Morphine.Media;
using WMPLib;
using Color = System.Windows.Media.Color;

namespace Morphine
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();


        }

        private void WindowSourceInitialized(object sender, EventArgs e)
        {
            var handle = new WindowInteropHelper(this).Handle;

            HwndSource.FromHwnd(handle).CompositionTarget.BackgroundColor = new Color();

            var margins = new WinAPI.Margins() { cyBottomHeight = 50 };

            Dwm.ExtendGlassFrame(handle, ref margins);

            this.Left = App.Settings.Left;
            this.Top = App.Settings.Top;
            this.Width = App.Settings.Width;
            this.Height = App.Settings.Height;

            PlayListColumnDefinition.MaxWidth = this.Width / 3;
            PlayListColumnDefinition.Width = new GridLength(App.Settings.PlaylistWidth);

            LocationChanged += WindowLocationChanged;
            SizeChanged += WindowSizeChanged;

            App.MediaPlayer.MediaChange += MediaPlayerMediaChange;
            App.MediaPlayer.PlayStateChange += MediaPlayerPlayStateChange;
            App.MediaPlayer.PlaylistChange += MediaPlayerPlaylistChange;

            App.MediaProgressTimer.Tick += MediaProgressTimerTick;

            if (App.MediaPlayer.currentPlaylist.count > 0)
            {
                var p = (IWMPPlaylist)App.MediaPlayer.currentPlaylist;
                if (App.MediaPlayer.currentPlaylist == p)
                    return;
                Playlist.Items.Clear();

                for (var i = 0; i < p.count; i++)
                {
                    var info = MediaInfo.GetInfo(p.Item[i]);
                    Playlist.Items.Add(info);
                }

                MediaPlayerMediaChange(App.MediaPlayer.currentMedia);
            }

            if (App.MediaPlayer.playState == WMPPlayState.wmppsPlaying)
                PlayButton.IsChecked = true;

            VolumeSlider.Value = App.Settings.Volume;
            if (App.Settings.Shuffle)
                ShuffleButton.IsChecked = true;
        }

        void MediaProgressTimerTick(object sender, EventArgs e)
        {
            TimeEstimatedTextBlock.Text = App.MediaPlayer.controls.currentPositionString;
            PositionSlider.Value = App.MediaPlayer.controls.currentPosition;
        }

        #region Media Player events

        void MediaPlayerMediaChange(object item)
        {
            if (item == null)
                return;

            PlayButton.IsEnabled = true;
            PrevButton.IsEnabled = true;
            NextButton.IsEnabled = true;
            StopButton.IsEnabled = true;
            PositionSlider.IsEnabled = true;

            var info = MediaInfo.GetInfo(App.MediaPlayer.currentMedia);
            if (MediaTitleTextBlock.Text == info.Title)
                return;
            MediaTitleTextBlock.Text = info.Title;
            ArtistNameTextBlock.Text = info.Artist;
            AlbumTitleTextBlock.Text = info.Album;
            PositionSlider.Maximum = App.MediaPlayer.currentMedia.duration;

            //var index = GetCurrentMediaIndex();
            //if (index >= 0)
            //    Playlist.Items[index] = info;

            Playlist.SelectedIndex = info.Index;//GetCurrentMediaIndex();

            PlaylistTitleTextBlock.Text = App.MediaPlayer.currentPlaylist.name;

            if (string.IsNullOrEmpty(info.Cover))
            {
                AlbumCover.Source = null;
                return;
            }
            if (AlbumCover.Source != null && ((BitmapImage)AlbumCover.Source).UriSource.LocalPath == info.Cover)
                return;

            var s = (Storyboard)Resources["ShowAlbumBgAnim"];
            s.Begin();
            if (!string.IsNullOrEmpty(info.Cover) && AlbumCover.Source == null)
                AlbumCover.Source = new BitmapImage(new Uri(info.Cover));
            else
                SwitchAlbumCovers(info.Cover);

            if (App.Settings.EnableDynamicColor)
            {
                var bmp = new Bitmap(info.Cover);
                var color = Utils.CalcAverageColor(bmp);
                PlayButton.Background = new SolidColorBrush(Color.FromRgb(color.R, color.G, color.B));
            }
        }


        void MediaPlayerPlayStateChange(int newState)
        {
            switch (newState)
            {
                case (int)WMPLib.WMPPlayState.wmppsPlaying:

                    PlayButton.IsChecked = true;
                    App.MediaProgressTimer.Start();
                    break;
                case (int)WMPLib.WMPPlayState.wmppsStopped:
                    PlayButton.IsChecked = false;
                    TimeEstimatedTextBlock.Text = "00:00";
                    App.MediaProgressTimer.Stop();
                    PositionSlider.Value = 0;
                    break;
                default:
                    PlayButton.IsChecked = false;
                    App.MediaProgressTimer.Stop();
                    break;
            }
        }

        void MediaPlayerPlaylistChange(object playlist, WMPPlaylistChangeEventType change)
        {
            var p = (IWMPPlaylist)playlist;
            switch (change)
            {
                case WMPPlaylistChangeEventType.wmplcClear:
                    var lastPlaylist = new List<MediaInfo>();
                    foreach (MediaInfo info in Playlist.Items)
                    {
                        lastPlaylist.Add(info);
                    }

                    Media.Playlist.Save(App.Path + "\\lastplaylist", lastPlaylist);

                    Playlist.Items.Clear();
                    break;
                case WMPPlaylistChangeEventType.wmplcAppend:
                    Playlist.Items.Clear();
                    for (var i = 0; i < p.count; i++)
                    {
                        var info = MediaInfo.GetInfo(p.Item[i]);
                        if (info.Type == "audio")
                            Playlist.Items.Add(info);
                    }
                    break;
                case WMPPlaylistChangeEventType.wmplcNameChange:
                    break;
                case WMPPlaylistChangeEventType.wmplcInfoChange:
                    Playlist.Items.Clear();
                    for (var i = 0; i < p.count; i++)
                    {
                        var info = MediaInfo.GetInfo(p.Item[i]);
                        if (info.Type == "audio")
                            Playlist.Items.Add(info);
                    }
                    break;
            }
        }

        #endregion

        private void WindowSizeChanged(object sender, SizeChangedEventArgs e)
        {
            PlayListColumnDefinition.MaxWidth = this.Width / 3;

            App.Settings.Width = this.Width;
            App.Settings.Height = this.Height;
        }

        private void WindowLocationChanged(object sender, EventArgs e)
        {
            App.Settings.Left = this.Left;
            App.Settings.Top = this.Top;
        }

        private void WindowClosed(object sender, EventArgs e)
        {
            LocationChanged -= WindowLocationChanged;
            SizeChanged -= WindowSizeChanged;

            App.MediaPlayer.MediaChange -= MediaPlayerMediaChange;
            App.MediaPlayer.PlayStateChange -= MediaPlayerPlayStateChange;
            App.MediaPlayer.PlaylistChange -= MediaPlayerPlaylistChange;

            App.MediaProgressTimer.Tick -= MediaProgressTimerTick;

            App.Settings.PlaylistWidth = PlayListColumnDefinition.Width.Value;
            App.Settings.Volume = (int)VolumeSlider.Value;
        }

        #region Context menu events

        private void OpenItemClick(object sender, RoutedEventArgs e)
        {
            var openDialog = new OpenFileDialog();
            openDialog.Multiselect = true;
            if (openDialog.ShowDialog() == true)
            {
                App.MediaPlayer.currentPlaylist.clear();

                var p = App.MediaPlayer.newPlaylist("Untitled", "");
                foreach (var name in openDialog.FileNames)
                {
                    var media = App.MediaPlayer.newMedia(name);
                    p.appendItem(media);
                    //App.MediaPlayer.currentPlaylist.appendItem(media);
                }

                App.MediaPlayer.currentPlaylist = p;
                App.MediaPlayer.controls.play();
                //Playlist.SelectedIndex = GetCurrentMediaIndex();
            }
        }

        private void CloseItemClick(object sender, RoutedEventArgs e)
        {
            this.Close();
        }

        #endregion

        private void SwitchAlbumCovers(string newCover)
        {
            OldAlbumCover.Source = AlbumCover.Source;
            if (!string.IsNullOrEmpty(newCover))
                AlbumCover.Source = new BitmapImage(new Uri(newCover));
            else
                AlbumCover.Source = null;

            var s = (Storyboard)Resources["SwitchAlbumCoverAnim"];
            s.Begin();
        }

        private void SwitchAlbumCoverAnimCompleted(object sender, EventArgs e)
        {
            OldAlbumCover.Source = null;
        }

        private void PlayListItemMouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            if (e.ClickCount > 1)
            {
                var index = Playlist.SelectedIndex;
                if (index < App.MediaPlayer.currentPlaylist.count)
                    App.MediaPlayer.controls.playItem(App.MediaPlayer.currentPlaylist.Item[index]);
            }
        }


        private void PlayButtonClick(object sender, RoutedEventArgs e)
        {
            if (App.MediaPlayer.playState == WMPPlayState.wmppsPlaying)
                App.MediaPlayer.controls.pause();
            else
                App.MediaPlayer.controls.play();
        }

        private void PrevButtonClick(object sender, RoutedEventArgs e)
        {
            App.MediaPlayer.controls.previous();
        }

        private void NextButtonClick(object sender, RoutedEventArgs e)
        {
            App.MediaPlayer.controls.next();
        }

        private void VolumeSliderValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            App.MediaPlayer.settings.volume = (int)VolumeSlider.Value;
        }

        private void StopButtonClick(object sender, RoutedEventArgs e)
        {
            App.MediaPlayer.controls.stop();
        }

        private void ShuffleButtonClick(object sender, RoutedEventArgs e)
        {
            if (App.Settings.Shuffle)
            {
                App.Settings.Shuffle = false;
                App.MediaPlayer.settings.setMode("shuffle", false);
            }
            else
            {
                App.Settings.Shuffle = true;
                App.MediaPlayer.settings.setMode("shuffle", true);
            }
        }

        private void MiniModeItemClick(object sender, RoutedEventArgs e)
        {
            var w = new MiniModeWindow();
            w.Show();
            App.Settings.IsMinimode = true;
            this.Close();
        }

        private void PositionSliderValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            var pos = Mouse.GetPosition(PositionSlider);
            if (Mouse.LeftButton == MouseButtonState.Pressed && this.IsActive && pos.X > 0 && pos.Y > 0 && pos.X < this.Width && pos.Y < 8)
                App.MediaPlayer.controls.currentPosition = PositionSlider.Value;
        }
    }
}
